home *** CD-ROM | disk | FTP | other *** search
- CG GROUP CODE_SEG
- ASSUME CS:CG, DS:CG
-
- ; PAGE 101 SOFTALK, JAN 1984
- ; This pprogram will search all directories for a given filename and print
- ; the full path name of each one found
- ; REVISIONS
- ; The scrolling limitation of 23 lines and the More? prompt with its N key
- ; exit were added by Ted Eyrick, Eytek, Inc., P.O. Box 160307, San Antonio,
- ; Texas 78280.
-
- DTA STRUC
- ; This is the format for the DOS Data Transfer Area used when DOS 2.0
- ; searches for a file match in directories
-
- RESERVED DB 21 DUP (?)
- ATTRIBUTE DB
- TIME DW
- DATE DW
- SIZE DD
- NAME_FOUND DB 13 DUP (?)
- DTA ENDS
-
-
- CODE_SEG SEGMENT
- ; This is the main program that sets up the initial conditions for
- ; SEARCH_DIRECTORY which, in turn, does a recursive search.
- ; Reads: PATH_NAME
- ; Writes: FILE_NAME
- ; Calls: SEARCH_DIRECTORY
-
- ORG 100H
-
- START:
- PUSH AX
- MOV AH,30H
- INT 21H
- CMP AL,2 ; Is it at least 2.0 ?
- JAE VERS_OK
- MOV DX,OFFSET WRONG_VERS
- CALL ERROR
- INT 20H
- VERS_OK:
- MOV AH,19H
- INT 21H ; Get the current drive #
- MOV [OLDDRIV],AL ; Save it
- POP AX
- CMP AL,-1 ; Is a valid drive named ?
- MOV DX,OFFSET CG:INVALID_DRIVE
- JNE TEST_UP
- BAD_DRIVE:
- CALL ERROR
- MOV AL,2 ; Error exit code
- JMP DOS_EXIT
- TEST_UP:
- CMP AH,-1
- JE BAD_DRIVE
- MOV SI,80H
- CMP BYTE PTR[SI],0 ; Any name specified
- NO_FILE:
- MOV DX,OFFSET CG:NONAME
- JE BAD_DRIVE
-
- PARSE_FILE:
- MOV DI,65H
- MOV CX,3
- MOV AL,'?'
- REP STOSB ; Put '.*' default
- MOV SI,[CMDLINE]
- CALL SCANOFF
- JNC GOOD_NAME
- MOV AL,0
- JMP DOS_EXIT
- GOOD_NAME:
- CMP BYTE PTR[SI],'\' ; Was it a pathname ?
- JNE NO_PATH
- CALL NEXT_BLANK ; Go to next filename
- MOV [CMDLINE],SI ; Ignore pathnames
- JMP PARSE_FILE
- NO_PATH:
- CMP BYTE PTR [FIRST],0
- JE FIRST_TIME ; Don't check first time around
- FIRST_TIME:
- MOV DX,SI
- CALL GET_CHAR_COUNT
- MOV DI,OFFSET SEARCH_NAME
- PUSH SI
- REP MOVSB
- POP SI
- MOV AL,0
- STOSB ; Set search name
- CALL PRINT_FILE_SEP
- MOV DI,5CH
- MOV AH,29H
- MOV AL,9 ; Ignore leading seps
- INT 21H
- CMP BYTE PTR[SI],'\' ; Was it a pathname ?
- JNE NO_PATH1
- CALL NEXT_BLANK ; Go to next filename
- MOV [CMDLINE],SI
- JMP PARSE_FILE
- NO_PATH1:
- MOV [CMDLINE],SI ; Save pointer for next time
-
- WHEREIS PROC NEAR
- MOV SI,5CH ; FCB
- LODSB
- CMP AL,0 ; Is it default drive ?
- JE IS_DEFAULT
- SUB AL,1 ; Convert to logical
- MOV DL,AL
- MOV [CURDRIVE],AL
- MOV AH,0EH
- INT 21H ; Select new drive
- JMP SHORT SEARCH
- IS_DEFAULT:
- MOV AL,[OLDDRIV]
- MOV [CURDRIVE],AL ; Save it
- SEARCH:
- MOV DI,OFFSET CG:FILE_NAME
- GET_SEARCH_NAME:
- CMP SI,65H ; End of FCB name ?
- JAE DONE_READING_NAME
- LODSB ; get first character
- CMP AL,' ' ; Is it space
- JE GET_SEARCH_NAME
- STOSB
- JMP GET_SEARCH_NAME
- DONE_READING_NAME:
- MOV AL,'.'
- STOSB
- READ_EXT:
- CMP SI,68H ; End of FCB ext ?
- JAE FCB_TO_ASCIZ
- LODSB
- CMP AL,' '
- JE READ_EXT
- STOSB
- JMP READ_EXT
- FCB_TO_ASCIZ:
- XOR AL,AL ; write a 0 at the end
- STOSB
- MOV DI,OFFSET CG:PATH_NAME
- CMP BYTE PTR[FILE_NAME+1],0 ; Is there a file ?
- JNE SEARCH_FILE
- MOV AL,0
- JMP DOS_EXIT
- SEARCH_FILE:
- OR AL,AL ; search for the zero at the end
- CLD ; of PATH_NAME
- MOV CX,64 ; Max. length of scan for 0
- REPNZ SCASB
- MOV BX,DI
- DEC BX
- MOV DX,0 ; DS:BX points to end of PATH-NAME
- CALL SEARCH_DIRECTORY ; now do the trcursive search
- MOV BYTE PTR[FIRST],-1 ; Now we`ll go again !
- CALL IS_MORE ; Is there more ?
- JAE FINISH
- JMP PARSE_FILE
- FINISH:
- MOV AL,0
- JMP DOS_EXIT ; all done now
- WHEREIS ENDP
-
- IS_MORE PROC NEAR
- ; Test to see if more filespecs are on command line
- MOV SI,80H
- XOR CX,CX
- MOV CL,[SI]
- MOV DI,81H
- ADD DI,CX ; Set DI to end of command line
- MOV SI,[CMDLINE]
- CMP SI,DI
- RET
- IS_MORE ENDP
-
- SEARCH_DIRECTORY PROC NEAR
- ; This procedure searches all the files in the current directory looking for a match.
- ; It also prints the fill name for each match.
-
- ; DS:BX
- ; DS:DX
-
- ; Reads: Disk Transfer Area (DTA)
- ; Writes: Disk Transfer Area
- ; Calls: BUILD_NAME, GET_FIRST_MATCH, WRITE_MATCHED_NAME, GET_NEXT_MATCH,
- ; BUILD_STAR_NAME, SEARCH_SUB_DIRECTORY
-
- PUSH SI ; NEED TO RESTORE ON EXIT
- PUSH DX
- CALL BUILD_NAME ; Build the absolute search name
- CALL GET_FIRST_MATCH ; See if there is a match here
- JC NO_MATCH ; no match, check subdirectories
- CALL WRITE_MATCHED_NAME ; write name of match
- FIND_NEXT_FILE:
- CALL GET_NEXT_MATCH ; find the next match
- JC NO_MATCH ; no match, search subdirectories
- CALL WRITE_MATCHED_NAME ; match, grite absolute name
- JMP FIND_NEXT_FILE ; look for the next matching name
- NO_MATCH:
- POP DX ; restore DTA
- PUSH DX
- CALL BUILD_STAR_NAME ; search for all directories
- CALL GET_FIRST_MATCH ; get first entry
- JC NO_MORE_MATCHES ; there are no entries
- MOV SI,DX ; put address of DTA into SI
- TEST [SI].ATTRIBUTE,10H ; is it a directory entry?
- JNZ IS_DIRECTORY ; yes, then search subdirectory
- FIND_NEXT_DIRECTORY:
- CALL GET_NEXT_MATCH ; no, then find the next match
- JC NO_MORE_MATCHES ; there are no more entries
- TEST [SI].ATTRIBUTE,10H ; is this a directory?
- JZ FIND_NEXT_DIRECTORY ; no, then try again
- IS_DIRECTORY:
- CMP [SI].NAME_FOUND,'.' ; is this a . or .. directory?
- JE FIND_NEXT_DIRECTORY ; yes, skip to next directory
- CALL SEARCH_SUB_DIRECTORY ; search the subdirectory
- PUSH AX ; now reset the DTA
- MOV AH,1AH
- INT 21H
- POP AX
- JMP FIND_NEXT_DIRECTORY
- NO_MORE_MATCHES:
- POP DX
- POP SI
- RET
- SEARCH_DIRECTORY ENDP
-
- SEARCH_SUB_DIRECTORY PROC NEAR
- ; This procedure searches the subdirectory whose name is in the DTA
- ; DS:BX end of the current pathname
- ; ds:[dx].name_found name of subdirectory for search
- ; reads: path_name
- ; writes: path_name
- ; calls: search_directory
- PUSH DI
- PUSH SI
- PUSH AX
- PUSH BX
- CLD
- MOV SI,DX ; put address of DTA into SI
- ADD SI,OFFSET NAME_FOUND ; set to start of subdirectory name
- MOV DI,BX
- COPY_LOOP:
- LODSB
- STOSB
- OR AL,AL ; was it a 0
- JNZ COPY_LOOP ; no, keep copying
- MOV BX,DI ;set BX to end of new pathname
- STD ; set flag for decrement
- STOSB ; store a 0 at end of string
- MOV AL,'\'
- STOSB ; place '\' at end of pathname
- CALL SEARCH_DIRECTORY ; search this new path
- POP BX ; restore the old end-of-paht
- MOV BYTE PTR [BX],0 ; and store a zero here
- POP AX
- POP SI
- POP DI
- RET
- SEARCH_SUB_DIRECTORY ENDP
-
- WRITE_MATCHED_NAME PROC NEAR
- ; This procedure prints the matched name after the path name
- PUSH AX
- PUSH DX
- MOV DL,[CURDRIVE]
- ADD DL,'A' ; Convert to ASCII
- MOV AH,2
- INT 21H
- MOV DL,':'
- INT 21H
- MOV DX,OFFSET CG:PATH_NAME
- MOV AL,[BX] ; Save character at end of path
- MOV BYTE PTR[BX],0 ; End of string mark
- CALL WRITE_STRING
- MOV [BX],AL
- POP DX
- PUSH DX ; Restore old pointer
- ADD DX,OFFSET NAME_FOUND
- CALL WRITE_STRING
- CALL SEND_CRLF
- INC LINCTR ;inc line counter
- MOV AL,23 ;test for 23 lines printed
- CMP AL,LINCTR
- JNE WRITEXIT ;no_normal exit
- MOV AL,0 ;23 printed, so send
- MOV LINCTR,AL ;message
- MOV DX,OFFSET CG:PROMPT
- MOV AH,9
- INT 21H
- MOV AH,0
- INT 16H
- CMP AL,'N'
- JE DOS_EXIT
- CMP AL,'n'
- JE DOS_EXIT
- WRITEXIT:
- POP DX
- POP AX
- RET
- WRITE_MATCHED_NAME ENDP
-
- BUILD_NAME PROC NEAR
- PUSH SI
- MOV SI,OFFSET CG:FILE_NAME
- CALL BUILD
- POP SI
- RET
- BUILD_NAME ENDP
-
- BUILD_STAR_NAME PROC NEAR
- PUSH SI
- MOV SI,OFFSET CG:STAR_NAME
- CALL BUILD
- POP SI
- RET
- BUILD_STAR_NAME ENDP
-
- BUILD PROC NEAR
- PUSH AX
- PUSH DI
- MOV DI,BX
- CLD
- COPY_NAME:
- LODSB
- STOSB ; Get 1 character of name
- OR AL,AL ; End of string ?
- JNZ COPY_NAME
- POP DI
- POP AX
- RET
- BUILD ENDP
-
- GET_FIRST_MATCH PROC NEAR
- PUSH CX
- CMP DX,0 ; 1st one ?
- JA ALLOCATE ; No, then make some space
- MOV DX,OFFSET CG:DISK_TRANSFER_AREAS-TYPE DTA
- ALLOCATE:
- ADD DX,TYPE DTA ; No,then allocate room for new DTA
- MOV CX,10H ; Search attribute
- MOV AH,1AH
- INT 21H
- PUSH DX
- MOV DX,OFFSET CG:PATH_NAME
- MOV AH,4EH ; Call for "find first match"
- INT 21H
- POP DX
- POP CX
- RET
- GET_FIRST_MATCH ENDP
-
- GET_NEXT_MATCH PROC NEAR
- PUSH CX
- PUSH DX
- MOV DX,OFFSET CG:PATH_NAME
- MOV CX,10H
- MOV AH,4FH
- INT 21H
- POP DX
- POP CX
- RET
- GET_NEXT_MATCH ENDP
-
- SEND_CRLF PROC NEAR
- PUSH AX
- PUSH DX
- MOV AH,2
- MOV DL,0AH
- INT 21H
- MOV DL,0DH
- INT 21H
- POP DX
- POP AX
- RET
- SEND_CRLF ENDP
-
- WRITE_STRING PROC NEAR
- PUSH AX
- PUSH DX
- PUSH SI
- CLD
- MOV SI,DX
- MOV AH,2
- LODSB
- WRITE_STRING_LOOP:
- MOV DL,AL
- INT 21H
- LODSB
- OR AL,AL ; End of string ?
- JNZ WRITE_STRING_LOOP
- POP SI
- POP DX
- POP AX
- RET
- WRITE_STRING ENDP
-
- ERROR PROC NEAR
- MOV AH,9
- INT 21H
- RET ; Print message
- ERROR ENDP
-
- DOS_EXIT PROC NEAR
- MOV DL,[OLDDRIV]
- MOV AH,0EH
- INT 21H
- MOV AH,4CH
- INT 21H
- DOS_EXIT ENDP
-
- GET_CHAR_COUNT PROC NEAR
- PUSH SI
- MOV SI,DX
- XOR CX,CX
- CHAR_COUNT:
- LODSB
- CMP AL,' '
- JBE CHAR_COUNT_RET
- INC CX
- JMP CHAR_COUNT
- CHAR_COUNT_RET:
- POP SI
- RET
- GET_CHAR_COUNT ENDP
-
-
- PRINT_FILE_SEP PROC NEAR
- PUSH DX
- PUSH CX
- MOV DX,OFFSET CRLF_STR
- MOV AH,9
- INT 21H
- MOV DX,OFFSET SEARCH_NAME
- CALL GET_CHAR_COUNT
- PUSH CX
- MOV BX,1
- MOV AH,40H
- INT 21H ; Print search name
- POP CX ; How many characters in name ?
- MOV DX,OFFSET FILE_SEP
- ADD DX,CX
- CALL ERROR
- POP CX
- POP DX
- RET
- PRINT_FILE_SEP ENDP
-
-
- SCANOFF PROC NEAR
- PUSH BX
- PUSH CX
- SCANOFF_CMP:
- LODSB
- CMP AL,' '
- JBE SCANOFF_CMP
- DEC SI
- ; Don't go beyond command line
- MOV BX,80H
- MOV CL,[BX]
- XOR CH,CH
- ADD CX,81H
- CMP SI,CX
- JB SCANOFF_RET
- MOV SI,CX ; Point to end of command line
- STC
- POP CX
- POP BX
- RET
- SCANOFF_RET:
- CLC
- POP CX
- POP BX
- RET
- SCANOFF ENDP
-
- NEXT_BLANK PROC NEAR
- ; Set SI to point to next blank character
- LODSB
- CMP AL,','
- JA NEXT_BLANK
- DEC SI
- RET
- NEXT_BLANK ENDP
-
-
- INVALID_DRIVE DB 'Bad drive specified',13,10,'$'
- NONAME DB 'No filename specified',13,10,'$'
- WRONG_VERS DB 'MS-DOS must be at least version 2.0',13,10,'$'
- FILE_SEP DB '---------------------------------------------',13,10,'$'
- CRLF_STR DB 13,10,'$'
- OLDDRIV DB 0
- CURDRIVE DB 0
- FIRST DB 0
- LINCTR DB 0
- PROMPT DB ' More ?',0AH,0DH,'$'
- CMDLINE DW 81H
- STAR_NAME DB '*.*',0
- PATH_NAME DB '\',0
- DB 80 DUP (0) ; space for 64 character pathname and 13 character filename
- FILE_NAME DB 13 DUP (0)
- SEARCH_NAME DB 13 DUP (0)
- DISK_TRANSFER_AREAS LABEL BYTE
-
- CODE_SEG ENDS
-
- END START